// 引入其他类
import Snake from "./Snake";
import Food from "./Food";
import ScorePanel from "./ScorePanel";

// 游戏控制器
class GameControl {
    // 蛇
    snake: Snake
    // 食物
    food: Food
    // 积分面板
    scorePanel: ScorePanel
    // 创建一个属性来表示蛇的移动方向
    direction: string = 'Right'

    // 创建一个属性用来记录游戏是否结束（蛇死没死）
    isLive = true

    constructor() {
        this.snake = new Snake()
        this.food = new Food()
        this.scorePanel = new ScorePanel(10, 2)
        this.init()

    }

    // 游戏初始化方法，调用后游戏即开始
    init() {
        // 绑定键盘按下的事件
        document.addEventListener('keydown', this.keydownHandler.bind(this))// 使用bind限制this始终为当前ganmeControl对象
        // 调用run方法，使蛇来移动
        this.run()
    }

    // 创建键盘按下响应函数
    keydownHandler(e: KeyboardEvent) {
        // 检查e.key的值是否合法（用户是否按了正确的按键）
        // 储存direction属性
        this.direction = e.key

    }

    // 创建控制蛇移动的方法
    run() {
        /*
        * 根据方向(this.direction)来使蛇的位置改变
        *       向上 top 减少
        *       向上 top 增加
        *       向左  left 减少
        *       向右  left 增加
        * */
        // 获取蛇现在的坐标
        let X = this.snake.X
        let Y = this.snake.Y
        // 根据按键方向来计算X、Y值
        switch (this.direction) {
            case "ArrowUp":
            case "Up":
                // 向上移动
                Y -= 10
                break
            case "ArrowDown":
            case "Down":
                // 向下移动
                Y += 10
                break
            case "ArrowLeft":
            case "Left":
                // 向左移动
                X -= 10
                break
            case "ArrowRight":
            case "Right":
                // 向右移动
                X += 10
                break


        }
        // 检查蛇是否吃到了食物
        this.checkEat(X, Y)
        // 修改蛇的X、Y值
        try {
            this.snake.X = X
            this.snake.Y = Y
        } catch (e) {
            // 进入到catch，说明出现了异常，捕获异常，游戏结束，弹出提示信息
            alert(e.message)
            // 将islive设为false，结束游戏
            this.isLive = false
        }


        // 开启定时调用，使蛇能不断移动,类似递归,定时时间根据游戏等级来计算，使得蛇的速度越来越快
        this.isLive && setTimeout(this.run.bind(this), 200 - (this.scorePanel.level - 1) * 20)
    }

    // 定义一个方法，用来检查蛇是否吃到食物
    checkEat(X: number, Y: number) {
        if (X === this.food.X && Y === this.food.Y) {
            console.log("吃到食物了！")
            // 重置食物的位置
            this.food.change()
            // 分数增加
            this.scorePanel.addScore()
            // 蛇要增加一节
            this.snake.addBody()
        }
    }
}

export default GameControl